home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Tools / Win95 Secrets / SETUP.Z / WALKHP2.C < prev    next >
Encoding:
C/C++ Source or Header  |  1995-07-19  |  6.8 KB  |  241 lines

  1. //==================================
  2. // WALKHP2 - Matt Pietrek 1995
  3. // FILE: WALKHP2.C
  4. //==================================
  5.  
  6. #include <windows.h>
  7. #include <stdio.h>
  8. #include "heapw32.h"
  9.  
  10. // Prototypes
  11. HANDLE WalkHeap( HANDLE hHeap );
  12. void DisplayFreeBlock( PFREE_HEAP_ARENA_RETAIL pFreeArena );
  13. void DisplayInUseBlock( PHEAP_ARENA_RETAIL pArena );
  14. void DisplayHeapFlags( BYTE flags );
  15. void MakeSomeAllocationsAndDeletions( HANDLE hHeap );
  16.  
  17. int main(int argc, char * argv[])
  18. {
  19.     HANDLE heap, anotherHeap;
  20.  
  21.     if ( (GetVersion() & 0xC0000000) != 0xC0000000 )
  22.     {
  23.         printf("WALKHEAP will only work with Win95\n");
  24.         return 0;       
  25.     }
  26.     
  27.     if ( GetSystemMetrics(SM_DEBUG) )
  28.     {
  29.         printf("WALKHP2 will only work with the retail version of Win95\n");
  30.         return 0;
  31.     }
  32.     
  33.     if ( argc == 2 )    // If user supplied an hHeap to walk, do it.
  34.     {
  35.         HANDLE hHeap;
  36.         
  37.         if ( 1 == sscanf( argv[1], "%x", &hHeap ) )
  38.         {
  39.             WalkHeap( hHeap );
  40.         }
  41.         else
  42.             printf( "Syntax: \"WALKHEAP <hHeap>\" or just \"WALKHEAP\"\n");
  43.  
  44.         return 0;
  45.     }
  46.  
  47.     // No command line was specified.  Do default action.
  48.  
  49.     heap = GetProcessHeap();
  50.  
  51.     // First, make the main heap look more interesting
  52.     MakeSomeAllocationsAndDeletions( heap );
  53.  
  54.     // Create another heap to show heap chaining.
  55.     anotherHeap = HeapCreate( HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE,
  56.                               0x80000, 0x100000 );
  57.  
  58.     // Walk all the heaps in the process.  New heaps are put at the head
  59.     // of the list.
  60.     heap = anotherHeap;
  61.     while ( heap )
  62.         heap = WalkHeap( heap );
  63.  
  64.     return 0;
  65. }
  66.  
  67. #define WIDTH 40
  68.  
  69. // Returns HANDLE for next heap in process, or 0 on failure
  70. HANDLE WalkHeap( HANDLE hHeap )
  71. {
  72.     PHEAP_HEADER_RETAIL pHeapHeader = (PHEAP_HEADER_RETAIL)hHeap;
  73.     PHEAP_ARENA_RETAIL pArena;
  74.     PFREE_LIST_HEADER_RETAIL pFreeListHdr;
  75.     unsigned i;
  76.  
  77.     if (   IsBadReadPtr( pHeapHeader, sizeof(HEAP_HEADER_RETAIL))
  78.         || pHeapHeader->signature != 0x4948 )
  79.     {
  80.         printf("%08X is not a valid heap handle\n", hHeap);
  81.         return 0;
  82.     }
  83.     
  84.     printf("Heap at %08X\n", pHeapHeader);
  85.     
  86.     printf("%-*s%08X\n", WIDTH, "size:", pHeapHeader->dwSize);
  87.  
  88.     printf("%-*s%08X\n", WIDTH, "next block:", pHeapHeader->nextBlock);
  89.  
  90.     printf("Free lists:\n");
  91.     pFreeListHdr = pHeapHeader->freeListArray;
  92.     
  93.     for ( i=0; i < 4; i++ )
  94.     {
  95.         printf("  Head:%08X  size: %X\n",
  96.                 &pFreeListHdr->freeArena,
  97.                 pFreeListHdr->dwMaxBlockSize);
  98.         pFreeListHdr++;     // Advance to next free list header
  99.     }
  100.  
  101.     printf("%-*s%08X\n", WIDTH, "Next heap:", pHeapHeader->nextHeap);
  102.  
  103.     printf("%-*s%08X\n", WIDTH, "CritSection:", pHeapHeader->pCriticalSection);
  104.  
  105.     // CRITICAL_SECTION criticalSection;    // 0x7C
  106.  
  107.     printf("%-*s%02X\n", WIDTH, "Flags:", pHeapHeader->flags);
  108.     DisplayHeapFlags( pHeapHeader->flags );
  109.     printf("%-*s%04X\n", WIDTH, "Signature:", (WORD)pHeapHeader->signature);
  110.  
  111.     // The first arena starts after the heap header.  (The "+1" is C ptr math)
  112.     pArena = (PHEAP_ARENA_RETAIL)(pHeapHeader+1);
  113.  
  114.     printf("\nHeap Blocks\n");
  115.     printf("Block     Stat  Size      \n"
  116.            "--------  ----  --------  \n");
  117.  
  118.     pFreeListHdr = pHeapHeader->freeListArray;
  119.     for ( i=0; i < 4; i++ )
  120.     {
  121.         DisplayFreeBlock( &pFreeListHdr->freeArena );
  122.         pFreeListHdr++;     // Point at next free list head
  123.     }
  124.  
  125.     printf("\n");
  126.     
  127.     while ( 1 )
  128.     {
  129.         DWORD blockSize = pArena->size & ~0xA0000003;
  130.  
  131.         if ( blockSize == 0 )
  132.             break;
  133.  
  134.         if ( pArena->size & 1 )
  135.             DisplayFreeBlock( (PFREE_HEAP_ARENA_RETAIL)pArena );
  136.         else
  137.             DisplayInUseBlock( pArena );
  138.  
  139.         // Advance to next block
  140.         pArena = (PHEAP_ARENA_RETAIL)((DWORD)pArena + blockSize);
  141.     }
  142.  
  143.     printf("\n\n");
  144.  
  145.     return pHeapHeader->nextHeap;
  146. }
  147.  
  148. void DisplayInUseBlock( PHEAP_ARENA_RETAIL pArena )
  149. {
  150.     printf("%08X  used  %08X\n",
  151.             pArena,
  152.             pArena->size & ~0xA0000003);   
  153. }
  154.  
  155. void DisplayFreeBlock( PFREE_HEAP_ARENA_RETAIL pFreeArena )
  156. {
  157.     printf("%08X  free  %08X  prev:%08X  next:%08X\n",
  158.             pFreeArena,
  159.             pFreeArena->arena.size & ~0xA0000003,
  160.             pFreeArena->prev,
  161.             pFreeArena->next);  
  162. }
  163.  
  164. void MakeSomeAllocationsAndDeletions( HANDLE hHeap )
  165. {
  166.     LPVOID ptrArray[20];
  167.  
  168.     ptrArray[0] = HeapAlloc( hHeap, 0, 0x4 );
  169.     ptrArray[1] = HeapAlloc( hHeap, 0, 0x8 );
  170.     ptrArray[2] = HeapAlloc( hHeap, 0, 0xC );
  171.     ptrArray[3] = HeapAlloc( hHeap, 0, 0x10 );
  172.     ptrArray[4] = HeapAlloc( hHeap, 0, 0x14 );
  173.  
  174.     ptrArray[5] = HeapAlloc( hHeap, 0, 0x24 );
  175.     ptrArray[6] = HeapAlloc( hHeap, 0, 0x28 );
  176.     ptrArray[7] = HeapAlloc( hHeap, 0, 0x2C );
  177.     ptrArray[8] = HeapAlloc( hHeap, 0, 0x30 );
  178.     ptrArray[9] = HeapAlloc( hHeap, 0, 0x34 );
  179.  
  180.     ptrArray[10] = HeapAlloc( hHeap, 0, 0xC4 );
  181.     ptrArray[11] = HeapAlloc( hHeap, 0, 0xC8 );
  182.     ptrArray[12] = HeapAlloc( hHeap, 0, 0xCC );
  183.     ptrArray[13] = HeapAlloc( hHeap, 0, 0xD0 );
  184.     ptrArray[14] = HeapAlloc( hHeap, 0, 0xD4 );
  185.  
  186.     ptrArray[15] = HeapAlloc( hHeap, 0, 0x224 );
  187.     ptrArray[16] = HeapAlloc( hHeap, 0, 0x228 );
  188.     ptrArray[17] = HeapAlloc( hHeap, 0, 0x22C );
  189.     ptrArray[18] = HeapAlloc( hHeap, 0, 0x230 );
  190.     ptrArray[19] = HeapAlloc( hHeap, 0, 0x234 );
  191.  
  192.     // Put some stuff into the < 0x20 free list
  193.     HeapFree( hHeap, 0, ptrArray[3] );
  194.     HeapFree( hHeap, 0, ptrArray[1] );
  195.  
  196.     // Put some stuff into the < 0x80 free list
  197.     HeapFree( hHeap, 0, ptrArray[8] );
  198.     HeapFree( hHeap, 0, ptrArray[6] );
  199.  
  200.     // Put some stuff into the < 0x200 free list
  201.     HeapFree( hHeap, 0, ptrArray[13] );
  202.     HeapFree( hHeap, 0, ptrArray[11] );
  203.  
  204.     // Put some stuff into the < 0xFFFFFFFF free list
  205.     HeapFree( hHeap, 0, ptrArray[18] );
  206.     HeapFree( hHeap, 0, ptrArray[16] );
  207.     
  208.     // allocate some really big blocks ( > 1MB )
  209.     HeapAlloc( hHeap, 0, 0x200000 );
  210.     HeapAlloc( hHeap, 0, 0x180000 );
  211. }
  212.  
  213. typedef struct
  214. {
  215.     BYTE    flag;
  216.     PSTR    name;
  217. } BYTE_FLAG_DESCRIPTIONS;
  218.  
  219. BYTE_FLAG_DESCRIPTIONS HeapFlags[] = 
  220. {
  221. { 0x00000001, "HEAP_NO_SERIALIZE" },
  222. { 0x00000002, "HEAP_GROWABLE" },
  223. { 0x00000004, "HEAP_GENERATE_EXCEPTIONS" },
  224. { 0x00000008, "HEAP_ZERO_MEMORY" },
  225. { 0x00000010, "HEAP_REALLOC_IN_PLACE_ONLY" },
  226. { 0x00000020, "HEAP_TAIL_CHECKING_ENABLED" },
  227. { 0x00000040, "HEAP_FREE_CHECKING_ENABLED" },
  228. { 0x00000080, "HEAP_DISABLE_COALESCE_ON_FREE" }
  229. };
  230. #define HEAP_FLAGS_COUNT ( sizeof(HeapFlags) / sizeof(HeapFlags[0]) )
  231.  
  232. void DisplayHeapFlags( BYTE flags )
  233. {
  234.     unsigned i;
  235.     
  236.     for ( i=0; i < HEAP_FLAGS_COUNT; i++ )
  237.         if ( HeapFlags[i].flag & flags )
  238.             printf("%-*s%s\n", WIDTH, "", HeapFlags[i].name);
  239. }
  240.  
  241.